/*
 *         Author:  slang (slang), songlang@corp.netease.com
 */

#include <netinet/in.h>
#include <sys/socket.h>
#include <fcntl.h>

#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>

#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

static void on_read_cb(bufferevent *bev, void *ctx)
{
	printf("read_cb ...\n");
    struct evbuffer *input, *output;
    input = bufferevent_get_input(bev);
    output = bufferevent_get_output(bev);

    char *line = NULL;
    size_t n;
    int i;

    line = evbuffer_readln(input, &n, EVBUFFER_EOL_LF);
	printf("data=%s\n", line);
}

static void on_event_cb(bufferevent *bev, short events, void *ctx)
{
	static int times = 1;
	if (events & BEV_EVENT_CONNECTED) {
		printf("connected server \n");
	} else if (events & (BEV_EVENT_TIMEOUT|BEV_EVENT_READING)) {
		printf( "timeout event ! times=%d  \n", times);
		if (times == 1) {
			bufferevent_write(bev, "aaabbb", 3);
			times ++;
		}
		bufferevent_enable(bev, EV_READ|EV_WRITE);
	} else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
		printf( "error or eof !\n");
		bufferevent_free(bev);
	}
}

int main(int argc, char **argv)
{
    struct event_base *base = event_base_new();
    if (!base) {
		return -1;
	}

    struct sockaddr_in sin;
    bzero(&sin, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(12345);

	struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev, on_read_cb, NULL, on_event_cb, NULL);
	struct timeval tv = {5, 0};
	bufferevent_set_timeouts(bev, &tv, NULL);
	bufferevent_enable(bev, EV_READ|EV_WRITE);
	bufferevent_socket_connect(bev, (struct sockaddr *)&sin, sizeof(sin));
	bufferevent_write(bev, "aaa\n", 4);

    printf("echo server run ....\n");
    event_base_dispatch(base);
	return 0;
}

